#include <i_fs.h>
#include <filesystem>
#include <i_string.h>

namespace std_fs = std::filesystem;

namespace fs
{
	MISC_DLL_EXPORT bool IsFileExists(const std::string& path_utf8)
	{
		std_fs::directory_entry entry(std_fs::u8path(path_utf8));
		return entry.exists() && !entry.is_directory();
	}

	MISC_DLL_EXPORT bool IsDirExists(const std::string& path_utf8)
	{
		std_fs::directory_entry entry(std_fs::u8path(path_utf8));
		return entry.exists() && entry.is_directory();
	}

	MISC_DLL_EXPORT bool MakeDir(const std::string& path_utf8)
	{
		return std_fs::create_directories(std_fs::u8path(path_utf8));
	}

	MISC_DLL_EXPORT void CopyFile(const std::string& src_path_utf8, const std::string& dst_path_utf8)
	{
		std_fs::copy_file(std_fs::u8path(src_path_utf8), std_fs::u8path(dst_path_utf8));
	}

	MISC_DLL_EXPORT int64_t GetFileLastWriteTime(const std::string& path_utf8)
	{
		std_fs::directory_entry entry(std_fs::u8path(path_utf8));
		std::error_code err;
		auto result = entry.last_write_time(err);
		if (err)
			return 0;

		return result.time_since_epoch().count();
	}

	MISC_DLL_EXPORT void ForeachFileInDir(const std::string& dir, const std::function<bool(const std::string& file)>& callback)
	{
		std_fs::path dir_path = std_fs::u8path(dir);
		for (auto& it : std_fs::directory_iterator(dir_path))
			callback(it.path().u8string());
	}

	MISC_DLL_EXPORT std::string& FormatPath(std::string& file)
	{
#ifdef _WIN32
		ReplaceCh(file, '\\', '/');
#endif
		return file;
	}

	MISC_DLL_EXPORT void SplitePath(const std::string& fullpath, std::string* dir, std::string* filename, std::string* filext)
	{
		std_fs::path path = std_fs::u8path(fullpath);
		if (dir != nullptr)
			*dir = path.parent_path().u8string();

		if (filename != nullptr)
			*filename = path.stem().u8string();

		if (filext != nullptr)
			*filext = path.extension().u8string();
	}
}

